package cn.antho.basic.service.impl;

import cn.antho.basic.config.BussinessException;
import cn.antho.basic.constant.BaseConstant;
import cn.antho.basic.dto.EmailCodeDto;
import cn.antho.basic.dto.PhoneSmsCodeDto;
import cn.antho.basic.service.IVerifyCodeService;
import cn.antho.basic.util.EmailUtil;
import cn.antho.basic.util.SmsSendUtil;
import cn.antho.basic.util.StrUtils;
import cn.antho.basic.util.VerifyCodeUtils;
import cn.antho.user.domain.User;
import cn.antho.user.mapper.UserMapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.concurrent.TimeUnit;

@Service
@Slf4j
public class VerifyCodeServiceImpl implements IVerifyCodeService {

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private UserMapper userMapper;



    /**
     * 获取图形验证码
     * @param uuidKey
     * @return
     */
    @Override
    public String getImageCode(String uuidKey) {
        // 生成随机数
        String randomCode = StrUtils.getComplexRandomString(4);
        // 存入到reids
        redisTemplate.opsForValue().set(uuidKey,randomCode,3, TimeUnit.MINUTES);
        // 生成图形验证码返回给前端
        return VerifyCodeUtils.VerifyCode(100, 35, randomCode);
    }

    /**
     * 获取手机验证码
     */
    @Override
    public void getSmsCode(PhoneSmsCodeDto dto) {
        // 验证参数是否为空
        // todo 手机号格式自己验证
        // 图形验证码是否正确
        if ("register".equals(dto.getType())) {
            String imageCode = (String) redisTemplate.opsForValue().get(dto.getImageCodeKey());
            if (StringUtils.isBlank(imageCode) || !imageCode.equalsIgnoreCase(dto.getImageCodeValue())) {
                throw new BussinessException("图形验证码错误！");
            }
            // 当前手机号是否已经注册了
            User user = userMapper.findByPhone(dto.getPhone());
            if (null != user){
                throw new BussinessException("该手机号已被注册，请登录！");
            }
            sendSms(dto, BaseConstant.VerfityCodeCons.REGISTER_SMSCODE_PHONE);
        } else if ("binder".equals(dto.getType())){
            sendSms(dto, BaseConstant.VerfityCodeCons.BINDER_SMSCODE_PHONE);
        } else if ("login".equals(dto.getType())) {
            sendSms(dto, BaseConstant.VerfityCodeCons.LOGIN_SMSCODE_PHONE);
        }
    }

    private void sendSms(PhoneSmsCodeDto dto, String key) {
        // 两次发送短信间隔是否大于60s
        // redis中 key：register:smscode:phone  value：验证码:时间戳
        String redisSmsCode = (String) redisTemplate.opsForValue().get(String.format(key,dto.getPhone()));
        String smsCode = "";
        if (StringUtils.isNotBlank(redisSmsCode)){
            // 不为空才做 60s校验  redisSmsCode 存的是 验证码:时间戳
            String[] split = redisSmsCode.split(":");
            smsCode = split[0];
            // 当前时间
            long newTime = System.currentTimeMillis();
            // reids中的时间
            long oldTime = Long.valueOf(split[1]);
            if (newTime - oldTime < 60 * 1000){
                throw new BussinessException("滚！");
            }
        } else {
            // 生成验证码
            smsCode = StrUtils.getRandomString(4);
        }
        log.info("验证码为：{}",smsCode);
        String redisValue = smsCode+":"+ System.currentTimeMillis();
        // 存入到reids
        redisTemplate.opsForValue().set(String.format(key,dto.getPhone()),
                redisValue,5,TimeUnit.MINUTES);
        // 发送短信
//        SmsSendUtil.sendSms(dto.getPhone(),"你好：你的验证码为："+smsCode+"，5分钟内有效！");
    }

    @Override
    public void getEmailCode(EmailCodeDto dto) {
        // 验证参数非空
        // 验证邮箱格式
        // 图形验证码是否正确
        String imageCode = (String) redisTemplate.opsForValue().get(dto.getImageCodeKey());
        if (StringUtils.isBlank(imageCode) || !imageCode.equalsIgnoreCase(dto.getImageCodeValue())){
            throw new BussinessException("图形验证码错误！");
        }
        // 验证邮箱是否被注册
        User user = userMapper.findByEmail(dto.getEmail());
        if (null != user){
            throw new BussinessException("该邮箱已被注册，请登录！");
        }
        // 两次发送短信间隔是否大于3min
        // redis中 key：register:emailcode:email  value：验证码:时间戳
        String redisEmailCode = (String) redisTemplate.opsForValue().get(String.format(BaseConstant.VerfityCodeCons.REGISTER_EMAILCODE_EMAIL,dto.getEmail()));
        String emailCode = "";
        if (StringUtils.isNotBlank(redisEmailCode)){
            // 不为空才做 3min校验  redisEmailCode 存的是 验证码:时间戳
            String[] split = redisEmailCode.split(":");
            emailCode = split[0];
            // 当前时间
            long newTime = System.currentTimeMillis();
            // reids中的时间
            long oldTime = Long.valueOf(split[1]);
            if (newTime - oldTime < 3 * 60 * 1000){
                throw new BussinessException("滚！");
            }
        }else {
            // 生成验证码
            emailCode = StrUtils.getRandomString(4);
        }
        log.info("验证码为：{}",emailCode);
        String redisValue = emailCode+":"+ System.currentTimeMillis();
        // 存入到reids
        redisTemplate.opsForValue().set(String.format(BaseConstant.VerfityCodeCons.REGISTER_EMAILCODE_EMAIL,dto.getEmail()),
                redisValue,15,TimeUnit.MINUTES);
        // 发送邮件
        EmailUtil.sendEmail("宠物之家邮箱注册验证码", "您好！您的验证码是：" + emailCode + "，15分钟内有效！", dto.getEmail());
    }
}
